<script>
import {getProductCategory, updateProductCategory} from "@/api/productCategory";
import {getUserInfo} from "@/utils/auth";

function traverse(categories, findID) {
  for (let i = 0; i < categories.length; i++) {
    const category = categories[i];

    if (category.id === findID) {
      return category;
    }

    if (category.children && category.children.length > 0) {
      const result = traverse(category.children, findID);
      if (result) {
        return result;
      }
    }
  }

  return null;
}

function generateId() {
  let result = '';
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const charactersLength = characters.length;

  for (let i = 0; i < 16; i++) {
    const randomIndex = Math.floor(Math.random() * charactersLength);
    result += characters.charAt(randomIndex);
  }

  return result;
}

function findParent(categories, findId, parent = null) {
  for (let i = 0; i < categories.length; i++) {
    const category = categories[i];

    if (category.id === findId) {
      return parent;
    }

    if (category.children && category.children.length > 0) {
      const result = findParent(category.children, findId, category);
      if (result) {
        return result;
      }
    }
  }

  return null;
}

export default {
  components: {},
  data() {
    return {
      currentnodekey: null,
      loading: false,
      data: [],
      id: generateId(),
      edit: false,
      aside_open_close: true,
    }
  },
  mounted() {
    this.getProductCategory();
  },
  methods: {
    getProductCategory() {
      if (this.loading)
        return;
      this.loading = true;
      getProductCategory({
        userID: getUserInfo().userID,
      }).then(res => {
        this.data = res.data.data.tree;
        this.loading = false;
        this.$nextTick(() => {
          if (!this.currentnodekey) {
            this.getCurrentKey({id: this.data[0].id});
          }  else {
            this.getCurrentKey({id: this.currentnodekey});
          }
        });
      });
    },
    getCurrentKey(v) {
      this.currentnodekey = v.id;
      this.$refs.tree.setCurrentKey(v.id);
      this.$emit('getCurrentNodeKey', v.id);
    },
    asidechange() {
      this.aside_open_close = !this.aside_open_close;
      this.$emit('statusChange', this.aside_open_close);
    },
    clickevent() {
      // 点击tree组件时  关闭右键菜单
      this.$refs.contextmenu.visible = false;
    },
    rename() {
      this.edit = true;
      this.$nextTick(() => {
        this.$refs.focus_input.focus()
      });
    },
    append() {
      this.id = generateId();
      const newChild = {id: this.id, label: '新分类', children: []};
      let currentNode = traverse(this.data, this.currentnodekey);
      if (!currentNode.children) {
        this.$set(currentNode, 'children', []);
      }
      currentNode.children.push(newChild);
      this.updateProductCategory(currentNode);
    },
    updateProductCategory(currentNode) {
      if (this.loading) {
        return;
      }
      if (!currentNode) {
        currentNode = {
          id: this.currentnodekey,
        }
      }

      this.loading = true;
      updateProductCategory({
        userID: getUserInfo().userID,
        treeData: this.data,
      }).then(res => {
        this.data = res.data.data.tree;
        this.loading = false;
        this.$nextTick(() => {
          this.getCurrentKey({id: currentNode.id});
        });
      });
    },
    inputblur() {
      this.updateProductCategory({
        id: this.currentnodekey,
      });
      this.edit = false;
    },
    remove() {
      const parent = findParent(this.data, this.currentnodekey);
      const children = parent.children || parent;
      const index = children.findIndex(d => d.id === this.currentnodekey);
      children.splice(index, 1);
      console.log(parent.id)
      this.updateProductCategory(parent);
    },
  }
}
</script>

<template>
  <div style="position: relative; height: 100%;" v-contextmenu:contextmenu>
    <el-card v-if="aside_open_close" v-loading="loading" class="box-card" shadow="hover"
             style="width: 250px; height: 100%; ">
      <div style="height: 35px; display: flex; position: relative; align-items: center;">
        <div style="color: #646a73;  user-select: none; font-size: 14px; font-weight: 500;">商品分类</div>
        <el-tooltip class="item" effect="dark" content="创建分类" placement="top">
          <i @click="append" class="el-icon-plus product-manager-icon" style="position: absolute; cursor: pointer; padding: 2px; right: 0;"></i>
        </el-tooltip>
      </div>
      <el-tree style="height: 100%; width: 225px; overflow-y: auto;  " highlight-current
               :current-node-key="currentnodekey" @node-click="clickevent"
               ref="tree" :data="data" node-key="id" default-expand-all @current-change="getCurrentKey"
               :expand-on-click-node="false">
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <input @blur="inputblur" @keyup.enter="inputblur" ref="focus_input" v-model="data.label"
                 v-if="data.id === currentnodekey && edit">
          <span :title="node.label" style="user-select: none; font-size: 14px; color: rgb(14, 14, 14);">
            <i style="margin-right: 2px;" class="el-icon-document"></i>{{ node.label }}
          </span>
        </span>
      </el-tree>
    </el-card>
    <div class="aside_open_close" @click="asidechange">
      <i class="el-icon-arrow-left" v-if="aside_open_close"></i>
      <i class="el-icon-arrow-right" v-else></i>
    </div>

    <v-contextmenu ref="contextmenu">
      <v-contextmenu-item @click="append">创建分类</v-contextmenu-item>
      <v-contextmenu-item @click="rename">重命名</v-contextmenu-item>
      <v-contextmenu-item :disabled="currentnodekey === 1" @click="remove">删除分类</v-contextmenu-item>
    </v-contextmenu>
  </div>
</template>

<style scoped lang="scss">
.aside_open_close {
  position: absolute;
  left: 0;
  top: 42%;
  width: 12px;
  height: 40px;
  line-height: 40px;
  color: #fff;
  background-color: #1890ff;
  border-radius: 0 6px 6px 0;
  font-size: 12px;
  z-index: 1000;
  cursor: pointer;
}

.aside_open_close:hover {
  background-color: #2A333A;
  color: #fff;
}

.main_aside {
  position: relative;
  margin: 0;
  padding: 0;
  background-color: #E9EEF3;
}

.product-manager-icon:hover {
  border-radius: 4px;
  background: rgba(31, 35, 41, 0.1);
  color: #2b2f36;
}
</style>
